//This is for clustering actions

#include "aux_functions_def.hpp"
#include "aux_functions_impl.hpp"


inline	
grassmann_points::grassmann_points( field<std::string> in_person_list,  field<std::string> in_action_list, double in_vec_size, int in_p)
{
  person_list =   in_person_list;  
  action_list =   in_action_list;
  vec_size =   in_vec_size;
  p = in_p;  
  creating_GrassField();
  
}

inline
void
grassmann_points::creating_GrassField()
{
  
  double n_points = person_list.n_rows*action_list.n_rows;
  
  GrassField.set_size(n_points,1); // Field with all Grassmann Points
  Labels_actions.set_size(n_points,1);
  uword pos = 0;
  
  
  for (uword s = 0; s < person_list.n_rows; ++s) // per subject(person)
  {
    for (uword a = 0; a <  action_list.n_rows; ++a)// per action
    {
      std::string pe = person_list(s,0);
      std::string ac = action_list(a,0);
      Labels_actions(pos,0) = ac;
      
      //cout << "Label is: " << Labels_actions(pos,0) << endl;
      
      std::stringstream folder;
      folder << "./actions_images/" << pe << ac << "/";
      
      //cout << "Loading file: " << folder.str() << endl;

      std::stringstream list_frames;
      list_frames << folder.str() << "list.txt";
      
      field<std::string>  name_frames;
      name_frames.load(list_frames.str());
      GrassField(pos,0) = creating_GrassPoint(name_frames,folder.str());
      pos++;
    }
  }
  //getchar();
}


inline
mat
grassmann_points::creating_GrassPoint(field<std::string>  name_frames, std::string folder)
{
  uword n_frames = name_frames.n_rows;
  mat F = zeros(vec_size,n_frames); //vec_size is an input
  
  for (uword n = 0; n < n_frames;  ++n)
  {
    std::stringstream tmp_name;
    tmp_name << folder << name_frames(n,0);
    cv::Mat cvImage;
    cvImage = cv::imread(tmp_name.str(), CV_LOAD_IMAGE_GRAYSCALE);
    
    //Showing Actions:
//     cv::namedWindow("Image", CV_WINDOW_AUTOSIZE );
//     cv::imshow("Image", cvImage);
//     cv::waitKey(50);
    //cout << cvImage.rows << " & "<<cvImage.rows << endl;
    
    aux_functions aux_fx;
    mat frame;
    frame = aux_fx.convert2Arma(cvImage); 
    mat tmp_frame;
    tmp_frame = reshape(frame,vec_size,1); 
    vec v = conv_to<vec>::from(tmp_frame);
    F.col(n) = v; // Image set
    
  }
  
  //Orthogonalization Procedure using SVD
  //Check it =).
  mat U; vec s;   mat V;
  svd(U,s,V,F); 
  
  //cout << "U.n_cols: "<< U.n_cols << endl;
  mat Gnp = U.cols(0,p-1);
  //cout << "F.   "  << "rows= "  << F.n_rows   <<  ". cols= "  << F.n_cols   << endl;
  //cout << "U.   "  << "rows= "  << U.n_rows   <<  ". cols= "  << U.n_cols   << endl;
  //cout << "s.   "  << "rows= "  << s.n_rows   <<  ". cols= "  << s.n_cols   << endl;
  //cout << "Gnp. "  << "rows= "  << Gnp.n_rows <<  ". cols= "  << Gnp.n_cols << endl;
  
  return Gnp;
}


inline
field<mat> 
grassmann_points::get_GrassPoints()
{
 return  GrassField;
}

inline
field<std::string> 
grassmann_points::get_labels()
{
 return   Labels_actions;
}

